package com.jie.langlangmall.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.util.StringUtil;
import com.jie.langlangmall.common.constant.DeleteStatus;
import com.jie.langlangmall.common.constant.StatusConstant;
import com.jie.langlangmall.dao.*;
import com.jie.langlangmall.dto.PmsProductParam;
import com.jie.langlangmall.dto.PmsProductQueryParam;
import com.jie.langlangmall.dto.PmsProductResult;
import com.jie.langlangmall.mapper.*;
import com.jie.langlangmall.model.*;
import com.jie.langlangmall.service.PmsProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author Jie
 * @Date 2024/9/12
 * @Email 3217998214@qq.com
 * @Description 后台商品管理
 */
@Service
@Slf4j
public class PmsProductServiceImpl implements PmsProductService {

    @Autowired
    private PmsProductMapper productMapper;
    @Autowired
    private PmsMemberPriceDao memberPriceDao;
    @Autowired
    private PmsProductLadderDao productLadderDao;
    @Autowired
    private PmsProductFullReductionDao productFullReductionDao;
    @Autowired
    private PmsSkuStockDao skuStockDao;
    @Autowired
    private PmsProductAttributeValueDao productAttributeValueDao;
    @Autowired
    private CmsSubjectProductRelationDao subjectProductRelationDao;
    @Autowired
    private CmsPrefrenceAreaProductRelationDao prefrenceAreaProductRelationDao;
    @Autowired
    private PmsProductDao productDao;
    @Autowired
    private PmsMemberPriceMapper memberPriceMapper;
    @Autowired
    private PmsProductLadderMapper productLadderMapper;
    @Autowired
    private PmsProductFullReductionMapper productFullReductionMapper;
    @Autowired
    private PmsSkuStockMapper skuStockMapper;
    @Autowired
    private CmsSubjectProductRelationMapper subjectProductRelationMapper;
    @Autowired
    private CmsPrefrenceAreaProductRelationMapper prefrenceAreaProductRelationMapper;
    @Autowired
    private PmsProductVertifyRecordDao productVertifyRecordDao;
    @Autowired
    private PmsProductAttributeValueMapper productAttributeValueMapper;

    /**
     * 添加商品
     *
     * @param productParam
     * @return
     */
    @Override
    public int create(PmsProductParam productParam) {
        // 添加商品
        productParam.setId(null);
        if (StringUtil.isEmpty(productParam.getUnit())) {
            productParam.setUnit("个");
        }
        productMapper.insertSelective(productParam);
        // 根据促销类型设置价格：会员价格、阶梯价格、满减价格
        Long productId = productParam.getId();
        // 添加会员价格
        relateAndInsertList(memberPriceDao, productParam.getMemberPriceList(), productId);
        // 添加阶梯价格
        relateAndInsertList(productLadderDao, productParam.getProductLadderList(), productId);
        // 添加满减价格
        relateAndInsertList(productFullReductionDao, productParam.getProductFullReductionList(), productId);
        // 处理sku的编码
        handleSkuStockCode(productParam.getSkuStockList(), productId);
        // 添加sku库存信息
        relateAndInsertList(skuStockDao, productParam.getSkuStockList(), productId);
        // 添加商品参数，添加自定义的商品规格
        relateAndInsertList(productAttributeValueDao, productParam.getProductAttributeValueList(), productId);
        // 关联专题
        relateAndInsertList(subjectProductRelationDao, productParam.getSubjectProductRelationList(), productId);
        // 关联优选
        relateAndInsertList(prefrenceAreaProductRelationDao, productParam.getPrefrenceAreaProductRelationList(), productId);

        return StatusConstant.SUCCESS;
    }

    /**
     * 商品的分页查询
     *
     * @param productQueryParam
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public List<PmsProduct> list(PmsProductQueryParam productQueryParam, Integer pageSize, Integer pageNum) {
        // 1. 开启分页查询
        PageHelper.startPage(pageNum, pageSize);

        // 2. 构建查询参数
        PmsProductExample example = new PmsProductExample();
        PmsProductExample.Criteria criteria = example.createCriteria();
        criteria.andDeleteStatusEqualTo(DeleteStatus.NO_DELETE.getCode());

        // 发布状态
        if (productQueryParam.getPublishStatus() != null) {
            criteria.andPublishStatusEqualTo(productQueryParam.getPublishStatus());
        }

        // 审核状态
        if (productQueryParam.getVerifyStatus() != null) {
            criteria.andVerifyStatusEqualTo(productQueryParam.getVerifyStatus());
        }

        // 关键字
        if (!StrUtil.isEmpty(productQueryParam.getKeyword())) {
            criteria.andNameLike("%" + productQueryParam.getKeyword() + "%");
        }

        // 商品货号
        if (!StrUtil.isEmpty(productQueryParam.getProductSn())) {
            criteria.andProductSnEqualTo(productQueryParam.getProductSn());
        }

        // 品牌
        if (productQueryParam.getBrandId() != null) {
            criteria.andBrandIdEqualTo(productQueryParam.getBrandId());
        }

        // 分类
        if (productQueryParam.getProductCategoryId() != null) {
            criteria.andProductCategoryIdEqualTo(productQueryParam.getProductCategoryId());
        }

        return productMapper.selectByExample(example);
    }

    /**
     * 根据商品id获取商品编辑信息
     *
     * @param id
     * @return
     */
    @Override
    public PmsProductResult getUpdateInfo(Long id) {
        return productDao.getUpdateInfo(id);
    }

    /**
     * 更新商品的信息
     *
     * @param id
     * @param product
     */
    @Override
    public void update(Long id, PmsProductParam product) {
        // 更新商品的信息
        product.setId(id);
        productMapper.updateByPrimaryKeySelective(product);
        // 更新会员价格表
        PmsMemberPriceExample memberPriceExample = new PmsMemberPriceExample();
        memberPriceExample.createCriteria().andProductIdEqualTo(id);
        memberPriceMapper.deleteByExample(memberPriceExample);
        relateAndInsertList(memberPriceDao, product.getMemberPriceList(), id);
        // 更新阶梯价格表
        PmsProductLadderExample ladderExample = new PmsProductLadderExample();
        ladderExample.createCriteria().andProductIdEqualTo(id);
        productLadderMapper.deleteByExample(ladderExample);
        relateAndInsertList(productLadderDao, product.getProductLadderList(), id);
        // 更新满减价格表
        PmsProductFullReductionExample reductionExample = new PmsProductFullReductionExample();
        reductionExample.createCriteria().andProductIdEqualTo(id);
        productFullReductionMapper.deleteByExample(reductionExample);
        relateAndInsertList(productFullReductionDao, product.getProductFullReductionList(), id);
        // 更新sku库存信息
        handleUpdateSkuStockList(id, product);
        // 修改关联专题
        CmsSubjectProductRelationExample subjectProductRelationExample = new CmsSubjectProductRelationExample();
        subjectProductRelationExample.createCriteria().andProductIdEqualTo(id);
        subjectProductRelationMapper.deleteByExample(subjectProductRelationExample);
        relateAndInsertList(subjectProductRelationDao, product.getSubjectProductRelationList(), id);
        // 修改关联优选
        CmsPrefrenceAreaProductRelationExample prefrenceAreaExample = new CmsPrefrenceAreaProductRelationExample();
        prefrenceAreaExample.createCriteria().andProductIdEqualTo(id);
        prefrenceAreaProductRelationMapper.deleteByExample(prefrenceAreaExample);
        relateAndInsertList(prefrenceAreaProductRelationDao, product.getPrefrenceAreaProductRelationList(), id);

    }

    /**
     * 根据货号查询
     *
     * @param keyword
     * @return
     */
    @Override
    public List<PmsProduct> list(String keyword) {
        PmsProductExample productExample = new PmsProductExample();
        PmsProductExample.Criteria criteria = productExample.createCriteria();
        criteria.andDeleteStatusEqualTo(0);
        if (!StrUtil.isEmpty(keyword)) {
            criteria.andNameLike("%" + keyword + "%");
            productExample.or().andDeleteStatusEqualTo(0).andProductSnLike("%" + keyword + "%");
        }
        return productMapper.selectByExample(productExample);
    }

    /**
     * 修改审核状态
     *
     * @param ids
     * @param verifyStatus
     * @param detail
     */
    @Override
    public void updateVerifyStatus(List<Long> ids, Integer verifyStatus, String detail) {
        PmsProduct product = new PmsProduct();
        product.setVerifyStatus(verifyStatus);
        PmsProductExample example = new PmsProductExample();
        example.createCriteria().andIdIn(ids);
        List<PmsProductVertifyRecord> list = new ArrayList<>();
        productMapper.updateByExampleSelective(product, example);
        //修改完审核状态后插入审核记录
        for (Long id : ids) {
            PmsProductVertifyRecord record = new PmsProductVertifyRecord();
            record.setProductId(id);
            record.setCreateTime(new Date());
            record.setDetail(detail);
            record.setStatus(verifyStatus);
            record.setVertifyMan("test");
            list.add(record);
        }
        // 插入审核记录表
        productVertifyRecordDao.insertList(list);
    }

    /**
     * 批量设置删除商品
     *
     * @param ids
     * @param deleteStatus
     */
    @Override
    @Transactional
    public void updateDeleteStatus(List<Long> ids, Integer deleteStatus) {
        PmsProduct record = new PmsProduct();
        record.setDeleteStatus(deleteStatus);
        PmsProductExample example = new PmsProductExample();
        example.createCriteria().andIdIn(ids);
        productMapper.updateByExampleSelective(record, example);
        // 删除商品的属性关联信息
        PmsProductAttributeValueExample productAttributeValueExample = new PmsProductAttributeValueExample();
        productAttributeValueExample.createCriteria().andProductIdIn(ids);
        productAttributeValueMapper.deleteByExample(productAttributeValueExample);
    }

    /**
     * 批量修改新品状态
     *
     * @param ids
     * @param newStatus
     */
    @Override
    public void updateNewStatus(List<Long> ids, Integer newStatus) {
        PmsProduct record = new PmsProduct();
        record.setNewStatus(newStatus);
        PmsProductExample example = new PmsProductExample();
        example.createCriteria().andIdIn(ids);
        productMapper.updateByExampleSelective(record, example);
    }

    /**
     * 推荐商品
     *
     * @param ids
     * @param recommendStatus
     */
    @Override
    public void updateRecommendStatus(List<Long> ids, Integer recommendStatus) {
        PmsProduct record = new PmsProduct();
        record.setRecommandStatus(recommendStatus);
        PmsProductExample example = new PmsProductExample();
        example.createCriteria().andIdIn(ids);
        productMapper.updateByExampleSelective(record, example);
    }

    /**
     * 商品上架、下架
     *
     * @param ids
     * @param publishStatus
     */
    @Override
    public void updatePublishStatus(List<Long> ids, Integer publishStatus) {
        // TODO: 商品上架，计入到ES中，商品下架，从ES中移除
        PmsProduct record = new PmsProduct();
        record.setPublishStatus(publishStatus);
        PmsProductExample example = new PmsProductExample();
        example.createCriteria().andIdIn(ids);
        productMapper.updateByExampleSelective(record, example);
    }

    /**
     * 更新库存信息
     *
     * @param id
     * @param product
     */
    private void handleUpdateSkuStockList(Long id, PmsProductParam product) {
        // 当前的sku信息
        List<PmsSkuStock> currSkuList = product.getSkuStockList();
        // 如果没有sku，则直接删除库存信息
        if (CollectionUtil.isEmpty(currSkuList)) {
            PmsSkuStockExample skuStockExample = new PmsSkuStockExample();
            skuStockExample.createCriteria().andProductIdEqualTo(id);
            skuStockMapper.deleteByExample(skuStockExample);
            return;
        }
        // 获取初始sku信息
        PmsSkuStockExample skuStockExample = new PmsSkuStockExample();
        skuStockExample.createCriteria().andProductIdEqualTo(id);
        List<PmsSkuStock> oriSkuList = skuStockMapper.selectByExample(skuStockExample);
        // 获取新增的sku信息
        List<PmsSkuStock> insertSkuList = currSkuList.stream().filter(item -> item.getId() == null).toList();
        // 获取需要更新的sku信息
        List<PmsSkuStock> updateSkuList = currSkuList.stream().filter(item -> item.getId() != null).toList();
        List<Long> updateSkuIds = updateSkuList.stream().map(PmsSkuStock::getId).toList();
        // 获取需要删除的sku信息
        List<PmsSkuStock> removeSkuList = oriSkuList.stream().filter(item -> !updateSkuIds.contains(item.getId())).toList();
        handleSkuStockCode(insertSkuList, id);
        handleSkuStockCode(updateSkuList, id);
        // 新增sku
        if (CollectionUtil.isNotEmpty(insertSkuList)) {
            relateAndInsertList(skuStockDao, insertSkuList, id);
        }
        // 删除sku
        if (CollectionUtil.isNotEmpty(removeSkuList)) {
            List<Long> removeSkuIds = removeSkuList.stream().map(PmsSkuStock::getId).toList();
            PmsSkuStockExample removeExample = new PmsSkuStockExample();
            removeExample.createCriteria().andIdIn(removeSkuIds);
            skuStockMapper.deleteByExample(removeExample);
        }
        // 修改sku
        if (CollUtil.isNotEmpty(updateSkuList)) {
            for (PmsSkuStock pmsSkuStock : updateSkuList) {
                skuStockMapper.updateByPrimaryKeySelective(pmsSkuStock);
            }
        }
    }

    /**
     * 处理sku的编码
     *
     * @param skuStockList
     * @param productId
     */
    private void handleSkuStockCode(List<PmsSkuStock> skuStockList, Long productId) {
        // 编码格式：日期+四位数的商品id+三位数的索引id
        // TODO: 编码会重复吗？怎么优化？
        if (!CollectionUtil.isEmpty(skuStockList)) {
            for (int i = 0; i < skuStockList.size(); i++) {
                PmsSkuStock skuStock = skuStockList.get(i);
                if (StrUtil.isEmpty(skuStock.getSkuCode())) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
                    // 日期
                    String sb = simpleDateFormat.format(new Date()) +
                            // 四位数的商品id
                            String.format("%04d", productId) +
                            // 三位数的索引id
                            String.format("%03d", i + 1);
                    skuStock.setSkuCode(sb);
                }
            }
        }
    }

    /**
     * 建立和插入关系表的操作
     *
     * @param dao
     * @param dataList
     * @param productId
     */
    private <T> void relateAndInsertList(Object dao, List<T> dataList, Long productId) {
        try {
            if (!CollectionUtil.isEmpty(dataList)) {
                // 通过java的反射调用每个item的setId和setProductId方法
                for (T item : dataList) {
                    Method setId = item.getClass().getDeclaredMethod("setId", Long.class);
                    setId.invoke(item, (Long) null);
                    Method setProductId = item.getClass().getMethod("setProductId", Long.class);
                    setProductId.invoke(item, productId);
                }
                // 调用数据库操作层dao的批量插入方法，将关系插入
                Method insertList = dao.getClass().getMethod("insertList", List.class);
                insertList.invoke(dao, dataList);
            }
        } catch (Exception e) {
            log.warn("创建商品出错：{}", e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }
}
